package com.culture.config.wrapper;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import com.culture.config.common.util.BeanUtil;
import com.culture.config.dao.entity.Menu;
import com.culture.config.dao.entity.User;
import com.culture.config.dao.entity.UserMenu;
import com.culture.config.model.MenuInfo;
import com.culture.config.model.po.*;
import com.culture.config.model.vo.*;
import com.culture.config.util.AuthenticationUtil;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@UtilityClass
public class MenuWrapper {
	public static MenuInfo wrapMenuInfo(User user, List<UserMenu> userMenuList) {
		MenuInfo menuInfo = new MenuInfo();
		if(CollectionUtils.isEmpty(userMenuList)) {
			return menuInfo;
		}
		List<UserMenu> rootMenuList = userMenuList.stream().filter(m->m.getParentId() <= 0).sorted(Comparator.comparing(UserMenu::getSortIndex)).collect(Collectors.toList());
		buildMenuTree(user,rootMenuList,userMenuList,0);
		return menuInfo.setMenuList(rootMenuList);
	}
	
	private static void buildMenuTree(User user, List<UserMenu> rootMenuList, List<UserMenu> userMenuList,int limit){
		log.debug("buildMenuTree:{}",limit);
		if(CollectionUtils.isEmpty(rootMenuList)) {
			return;
		}
		if(CollectionUtils.isEmpty(userMenuList)) {
			return;
		}
		if(limit > 10) {
			log.warn("buildMenuTree exceed limit level");
			return;
		}
	
		rootMenuList.forEach(m->{	
			m.setUserId(user.getId());
			m.setLevel(limit);
			m.setMenuList(userMenuList.stream().filter(child->m.getMenuId().equals(child.getParentId())).sorted(Comparator.comparing(UserMenu::getSortIndex)).collect(Collectors.toList()));			
			buildMenuTree(user,m.getMenuList(), userMenuList,limit + 1);
		});
	}	

	public static Menu wrapMenuQuery(MenuPageParam param) {
		Menu menu = new Menu();
	    menu.setParentId(param.getParentId());
		if(StringUtils.isNotBlank(param.getMenuName())){
			menu.setMenuName(param.getMenuName());
		}		
		return menu;
	}	

	public static Menu wrapMenuAdd(MenuAddPO menuAddPO) {
		Menu menu = BeanUtil.copyProperties(menuAddPO, Menu.class);
		menu.setDeleted(0);
		AuthenticationUtil.setInsertFieldInfo(menu);
		return menu;
	}
	
	public static Menu wrapMenuUpdate(MenuUpdatePO menuUpdatePO) {
		Menu menu = BeanUtil.copyProperties(menuUpdatePO, Menu.class);
		Optional.ofNullable(menuUpdatePO.getStatus()).ifPresent(status->menu.setDeleted(status));
		AuthenticationUtil.setUpdateFieldInfo(menu);	
		return menu;
	}

	public static Menu wrapMenuMove(MenuMovePO menuMovePO){
		Menu menu = new Menu(menuMovePO.getId());
		menu.setParentId(menuMovePO.getParentId());
		AuthenticationUtil.setUpdateFieldInfo(menu);
		return menu;
	}

	public static Menu wrapMenuSearch(MenuSearchPO param) {
		Menu menu = new Menu();	 
		if(StringUtils.isNotBlank(param.getMenuName())){
			menu.setMenuName(param.getMenuName());
		}		
		return menu;
	}	

	public static MenuTreeVO wrapMenuTreeVO(List<Menu> menuList) {
		MenuTreeVO menu = new MenuTreeVO();	 
		if(CollectionUtils.isEmpty(menuList)) {
			return menu;
		}
		List<MenuVO> menuVOList = BeanUtil.copyListProperties(menuList, MenuVO.class);
		List<MenuVO> rootMenuVOList = menuVOList.stream().filter(m->m.getParentId() <= 0).collect(Collectors.toList());
		wrapMenuTreeVOList(rootMenuVOList, menuVOList,0);
		return menu.setMenuList(rootMenuVOList);
	}

	private static void wrapMenuTreeVOList(List<MenuVO> rootMenuList, List<MenuVO> menuList,int limit){
		log.debug("wrapMenuTreeVOList:{}", limit);
		if(CollectionUtils.isEmpty(rootMenuList)) {
			return;
		}	
		if(limit > 10) {
			log.warn("wrapMenuTreeVOList exceed limit level");
			return;
		}
		rootMenuList.forEach(m->{			
			m.setMenuList(menuList.stream().filter(child->m.getId().equals(child.getParentId())).collect(Collectors.toList()));			
			wrapMenuTreeVOList(m.getMenuList(), menuList,limit + 1);
		});
	}	
}
